#pragma once
#include <iostream>
#include <memory>
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/bind.hpp>
using namespace boost::asio;

class client
{
public:
    virtual ~client() {}

    typedef client this_type;
    typedef ip::tcp::endpoint endpoint_type;
    typedef ip::address address_type;
    typedef ip::tcp::socket socket_type;
    typedef std::shared_ptr<socket_type> sock_ptr;
    typedef std::vector<char> buffer_type;

private:
    io_service m_io;
    buffer_type m_buf;
    endpoint_type m_ep;

public:
    client() : m_buf(100, 0), m_ep(address_type::from_string("127.0.0.1"), 8520)
    {
        start1();
    }

    void run()
    {
        m_io.run();
    }

    void start()
    {
        sock_ptr sock(new socket_type(m_io));
        sock->async_connect(m_ep,
            bind(&this_type::conn_handler, this,
                boost::asio::placeholders::error, sock));
    }

    //使用lambda表达式实现bind
    void start1() {
      sock_ptr sock(new socket_type(m_io));

      sock->async_connect(m_ep, 
          [this, sock](const boost::system::error_code& ec) 
        {
            std::cout << "1" << std::endl;
          if (ec)
          {
            std::cout << "error" << std::endl;
              return;
          }
          sock->async_read_some(buffer(m_buf), 
              [this, sock](const boost::system::error_code& ec, std::size_t)
          {
            std::cout << "4" << std::endl;
              read_handler(ec, sock);
          }
          );
        }
        );
    }


    void conn_handler(const boost::system::error_code& ec, sock_ptr sock) {
            std::cout << "2" << std::endl;
      if(ec)
      {
          return;
      }
      std::cout << "receive from server :" << sock->remote_endpoint().address() << std::endl;

      sock->async_read_some(buffer(m_buf),
          bind(&client::read_handler, this,
              boost::asio::placeholders::error, sock));
    }

    void read_handler(const boost::system::error_code& ec, sock_ptr sock)
    {
            std::cout << "3" << std::endl;
        if (ec)
        {
            std::cout << "555" << std::endl;
            std::cout << ec << std::endl;
            return;
        }
        std::cout << &m_buf[0] << std::endl;

        sock->async_read_some(buffer(m_buf),
            bind(&client::read_handler, this,
                boost::asio::placeholders::error, sock));
    }
};


// TcpSynClient.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>

int main()
{
    try
    {
        std::cout << "client start." << std::endl;
        client cl;
        cl.run();
    }
    catch (const std::exception& ec)
    {
        std::cout << ec.what() << std::endl;
    }
    getchar();
    std::cout << "Hello World!\n"; 
}
